package org.jw.wishlist.resolver;

import static com.google.common.base.Preconditions.checkArgument;

import cn.hutool.core.convert.Convert;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.jw.wishlist.entity.source.ItemSource;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

/**
 * @author Jiawei Zhao
 */
public abstract class ItemSourceSupports {

  protected static final ObjectMapper OBJECT_MAPPER;
  private static final Pattern URL_PATTERN = Pattern.compile("http\\S+");

  static {
    OBJECT_MAPPER = new ObjectMapper();
    OBJECT_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
  }

  protected final RestTemplate restTemplate;

  protected ItemSourceSupports(RestTemplate restTemplate) {
    this.restTemplate = restTemplate;
  }

  protected String extractUrl(String str) {
    Matcher matcher = URL_PATTERN.matcher(str);
    checkArgument(matcher.find(), "解析失败");
    return str.substring(matcher.start(), matcher.end());
  }

  protected <T> Optional<T> extractPropertyFromQueryString(String queryString, String name, Class<T> propertyType) {
    UriComponents uriComponents;
    if (queryString.startsWith("http")) {
      uriComponents = UriComponentsBuilder.fromHttpUrl(queryString).build();
    } else {
      uriComponents = UriComponentsBuilder.fromPath(queryString).build();
    }

    MultiValueMap<String, String> params = uriComponents.getQueryParams();

    return Optional.ofNullable(params.get(name))
        .map(x -> x.get(0))
        .map(x -> Convert.convert(propertyType, x));
  }

  @Setter
  @Accessors(fluent = true, chain = true)
  protected static class ProductItemSourceBuilder {

    private String itemId;

    private String name;

    private String key;

    private String linkCode;

    private String originUrl;

    private String accessUrl;

    private Integer version;

    private String pictureUrl;

    private String price;

    public ItemSource build() {

      Map<String, Object> extended = new LinkedHashMap<>();
      Optional.ofNullable(price)
          .ifPresent(x -> extended.put("price", x));

      return ItemSource.builder()
          .itemId(itemId)
          .key(key)
          .linkCode(linkCode)
          .name(name)
          .originUrl(originUrl)
          .pictureUrl(pictureUrl)
          .version(version)
          .accessUrl(accessUrl)
          .extended(extended)
          .build();
    }

  }

}
